package w83b.w83bOperacionesPaso.w83bComunicaciones;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.json.JSONObject;

import w83b.Thread.W83bNotificacionThread;
import w83b.w83bBeans.W83bComunicacionesBean;
import w83b.w83bBeans.W83bDocBean;
import w83b.w83bBeans.W83bUsuarioXLNetsBean;
import w83b.w83bUtilidadesComunes.W83bClsConstantes;
import w83b.w83bUtilidadesComunes.W83bClsTrazas;
import w83b.w83bUtilidadesComunes.W83bProperties;
import w83b.w83bUtilidadesComunes.W83bUtilidades;
import w83b.ws.aa66.W83bAa66NotificacionesWS;
import aa66.ejie.com.DestinatarioWs;
import aa66.ejie.com.EnvioOutWs;
import aa66.ejie.com.EnvioWs;
import aa66.ejie.com.ErrorWs;
import aa66.ejie.com.RemesaOutWs;
import aa66.ejie.com.RemesaWs;
import aa66.ejie.com.TipoRemesaAnonType;
import es.ejie.frmk.infraestructura.internacionalizacion.Q70GestorMensajesi18n;
import es.ejie.frmk.presentacion.operacion.paso.Q70ActionPasoOP;
import es.ejie.frmk.presentacion.sesiondatos.Q70ContextoEJIE;

// TODO: Auto-generated Javadoc
/**
 * The Class W83bEnvioCorrespondenciaActasLlamadaWSOPAction.java.
 *
 * @author Deusto Sistemas
 */
public class W83bEnvioCorrespondenciaActasLlamadaWSOPAction extends Q70ActionPasoOP{

	
	/* (non-Javadoc)
	 * @see es.ejie.frmk.presentacion.operacion.paso.Q70ActionPasoOP#processOP(es.ejie.frmk.presentacion.sesiondatos.Q70ContextoEJIE, org.apache.struts.action.ActionErrors, org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	protected void processOP(Q70ContextoEJIE contexto, ActionErrors errores, ActionMapping mapping,
			ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
			
	}

	/* (non-Javadoc)
	 * @see es.ejie.frmk.presentacion.operacion.paso.Q70ActionPasoOP#processForward(es.ejie.frmk.presentacion.sesiondatos.Q70ContextoEJIE, org.apache.struts.action.ActionErrors, org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	protected ActionForward processForward(Q70ContextoEJIE contexto, ActionErrors errors, ActionMapping mapping, 
			ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		String idioma = (String)contexto.get(W83bClsConstantes.CONSTANTE_CONTEXTO_IDIOMA);
		
		//Actas de los que se generara el acuse de recibo
		List lista=(List)contexto.get("w83bResultadoBean");
		
		//Datos de la selección del usuario
		W83bComunicacionesBean filtroUsuario=(W83bComunicacionesBean)contexto.get("w83bComunicacionesBean");
		
		
		//Troceamos los envios en bloques de no más de 180 envios
		List listabloquesEnvios = this.dividirBloques(lista);
		
		//Webservice
		W83bAa66NotificacionesWS aa66NotificacionesWS = new W83bAa66NotificacionesWS(W83bNotificacionThread.getTokenXLNets("w83b")); 
		
		//Lista de comunicaciones a guardar en base de datos como ok
		List listaComunicacionesConAcuse=null;
		
		//Recorremos la lista de bloques de envio y los vamos lanzando
		RemesaWs remesaEnvio;
		RemesaOutWs remesaOut=null;
		boolean hayEnvioCorrecto=false;
		boolean errorSistema=false;
		boolean errorEnvio=false;
		for (Iterator iter = listabloquesEnvios.iterator(); iter.hasNext();) {
			List enviosBloque = (ArrayList) iter.next();
			
			try {
				//********************************************
				//1. Preparamos la remesa
				//********************************************
				//1.1 Valores generales de la remesa
				remesaEnvio = new RemesaWs();
				W83bClsTrazas.trazaError(null, "INICIO BLOQUE ENVIOS ", null);
				
				String url = W83bProperties.getProperty("w83b","AA66_URL_WS");
		        if (url.indexOf("ejiedes")!=-1 || url.indexOf("ejiepru")!=-1) {
		        	remesaEnvio.setUidPuestoTramitador(W83bProperties.getProperty("w83b","TRAMITADOR_DESYPRU_AA66"));
		        	remesaEnvio.setTelefonoTramitador("000000000");
		        } else {
		        	remesaEnvio.setUidPuestoTramitador(((W83bUsuarioXLNetsBean)contexto.get(W83bClsConstantes.CONSTANTE_CONTEXTO_USUARIO)).getPuestouid());
		        	remesaEnvio.setTelefonoTramitador(((W83bUsuarioXLNetsBean)contexto.get(W83bClsConstantes.CONSTANTE_CONTEXTO_USUARIO)).getTelefonoPersona());
		        }
		        
		        //Comprobamos si viene telefono, en caso de que no metemos 000000000 para evitar el fallo
		        if(remesaEnvio.getTelefonoTramitador()==null || remesaEnvio.getTelefonoTramitador().equals("")){
		        	remesaEnvio.setTelefonoTramitador("000000000");
		        }
		        
		        
		        W83bClsTrazas.trazaError(null, "UidPuestoTramitador: "+remesaEnvio.getUidPuestoTramitador(), null);
		        W83bClsTrazas.trazaError(null, "TelefonoTramitador: "+remesaEnvio.getTelefonoTramitador(), null);
				
				if(StringUtils.isBlank(((W83bUsuarioXLNetsBean)contexto.get(W83bClsConstantes.CONSTANTE_CONTEXTO_USUARIO)).getMailPersona())){
					remesaEnvio.setRecibirMail(false);
				}else{
					remesaEnvio.setEmail(((W83bUsuarioXLNetsBean)contexto.get(W83bClsConstantes.CONSTANTE_CONTEXTO_USUARIO)).getMailPersona());
					remesaEnvio.setRecibirMail(true);
				}
				W83bClsTrazas.trazaError(null, "RecibirMail: "+remesaEnvio.getRecibirMail(), null);
				W83bClsTrazas.trazaError(null, "Email: "+remesaEnvio.getEmail(), null);
				
				remesaEnvio.setAplicacion(W83bProperties.getProperty("w83b","COD_APLICACION"));
				remesaEnvio.setAplicacionDescEs("Elecciones Sindicales");
				remesaEnvio.setAplicacionDescEu("Hauteskunde Sindikalak");
				
				W83bClsTrazas.trazaError(null, "Aplicacion: "+remesaEnvio.getAplicacion(), null);
				W83bClsTrazas.trazaError(null, "AplicacionDescEs: "+remesaEnvio.getAplicacionDescEs(), null);
				W83bClsTrazas.trazaError(null, "AplicacionDescEu: "+remesaEnvio.getAplicacionDescEu(), null);
				
				//Tipo de remesa
				if(filtroUsuario.getTipoRemesaEnviar().equals(W83bClsConstantes.TIPOREMESA_MASIVA)){
					remesaEnvio.setTipoRemesa(TipoRemesaAnonType.M);
				}else{
					remesaEnvio.setTipoRemesa(TipoRemesaAnonType.D);
				}
				W83bClsTrazas.trazaError(null, "TipoRemesa: "+remesaEnvio.getTipoRemesa(), null);
				
				//1.2 Lista Envios de la remesa
				W83bComunicacionesBean  comunicacionesBean;
				EnvioWs envio; 
				DestinatarioWs destinatario;
				List envios = new ArrayList();
				for (int i = 0; i < enviosBloque.size(); i++) {
					if(enviosBloque.get(i) instanceof  W83bComunicacionesBean){
						comunicacionesBean = (W83bComunicacionesBean)enviosBloque.get(i);
						envio = new EnvioWs();
						destinatario = new DestinatarioWs();
						//Destinatario
						if (comunicacionesBean.getCentroSel()==null||W83bClsConstantes.CONSTANTE_NO_VALIDADA.equals(comunicacionesBean.getCentroSel())||StringUtils.isEmpty(comunicacionesBean.getCporig())){
							destinatario.setCodigoPostal(comunicacionesBean.getCodigopostal());
						}else{
							destinatario.setCodigoPostal(comunicacionesBean.getCporig());
						}
						destinatario.setMunicipio(comunicacionesBean.getMunicipio());
						
						destinatario.setProvincia(comunicacionesBean.getProvincia());
						destinatario.setNombreApellidos(comunicacionesBean.getRazon());
						if (W83bClsConstantes.CONSTANTE_NO_VALIDADA.equals(comunicacionesBean.getCentroSel())||StringUtils.isEmpty(comunicacionesBean.getDirorig())){
							destinatario.setDireccion(W83bUtilidades.convertirAVasioSiNulo(comunicacionesBean.getDomicilio()).toUpperCase());
						}else{
							destinatario.setDireccion(W83bUtilidades.convertirAVasioSiNulo(comunicacionesBean.getDirorig()).toUpperCase());
						}
						W83bClsTrazas.trazaError(null, "CodigoPostal "+destinatario.getCodigoPostal(), null);
						W83bClsTrazas.trazaError(null, "Municipio "+destinatario.getMunicipio(), null);
						W83bClsTrazas.trazaError(null, "Provincia "+destinatario.getProvincia(), null);
						W83bClsTrazas.trazaError(null, "NombreApellidos "+destinatario.getNombreApellidos(), null);
						W83bClsTrazas.trazaError(null, "Direccion "+destinatario.getDireccion(), null);
						
						//Envios
						envio.setExpediente(Q70GestorMensajesi18n.getSingleton().getMessage("w83bcomun","comun.impugnaciones.acta",idioma,null)+" "+comunicacionesBean.getTerrit()+"/"+comunicacionesBean.getAnoacta()+"/"+W83bUtilidades.rellenarCaracter(comunicacionesBean.getNacta(), "0", 6, true));
						envio.setIdInterno(comunicacionesBean.getTerrit()+"/"+comunicacionesBean.getAnoacta()+"/"+W83bUtilidades.rellenarCaracter(comunicacionesBean.getNacta(), "0", 6, true));
						envio.setUidPuestoSolicitante(((W83bUsuarioXLNetsBean)contexto.get(W83bClsConstantes.CONSTANTE_CONTEXTO_USUARIO)).getPuestouid());
						
						W83bClsTrazas.trazaError(null, "Expediente "+envio.getExpediente(), null);
						W83bClsTrazas.trazaError(null, "IdInterno "+envio.getIdInterno(), null);
						W83bClsTrazas.trazaError(null, "UidPuestoSolicitante "+envio.getUidPuestoSolicitante(), null);
						
						envio.setDestinatario(destinatario);
						envios.add(envio);
					}
				}
				remesaEnvio.setListaEnvios((EnvioWs[])envios.toArray(new EnvioWs[envios.size()]));
	
				//********************************************
				//2. Envío
				//********************************************
				remesaOut= aa66NotificacionesWS.cargaMasiva(remesaEnvio);
				
				
				//********************************************
				//3. Tratamiento de respuesta
				//*********************************************
				if(remesaOut!=null && remesaOut.getErrores()==null && remesaOut.getIdremesa()!=W83bClsConstantes.ID_REMESA_ERROR){
					//3.1 ENVIO CORRECTO
					
					//3.1.1 Pasamos los datos de la remesaOut a una lista de comunicaciones
					listaComunicacionesConAcuse = new ArrayList();
					
					//3.1.2 Recorremos los envíos
					EnvioOutWs envioOutWs;
					W83bDocBean docBean;
					for (int i = 0; i < remesaOut.getEnvios().length; i++) {
						envioOutWs = (EnvioOutWs)remesaOut.getEnvios()[i];
						docBean = new W83bDocBean();
						
						//Datos del acta
						String[] idActa = envioOutWs.getIdInterno().split("/");
						docBean.setNumActaTerritorio(idActa[0]);
						docBean.setNumActaAno(idActa[1]);
						docBean.setNumActa(idActa[2]);
						
						//Datos del envio
						docBean.setIdRemesaAcuse(String.valueOf(remesaOut.getIdremesa()));
						docBean.setCodRemesaAcuse(remesaOut.getCodigoRemesa());
						docBean.setIdColeccionAcuse(String.valueOf(remesaOut.getIdColeccion()));
						docBean.setCodColeccionAcuse(remesaOut.getCodigoColeccion());
						docBean.setIdEnvioAcuse(String.valueOf(envioOutWs.getIdEnvio()));
						docBean.setCodEnvioAcuse(envioOutWs.getCodEnvio());
						
						listaComunicacionesConAcuse.add(docBean);
						
						hayEnvioCorrecto=true;
					}
					
				
				}else{
					//3.2 ENVIO INCORRECTO: se termina de enviar el resto de los lotes
					errorEnvio=true;
					break;
				}
			} catch (Exception e) {
				//Error de sistema: se termina de enviar el resto de los lotes
				errorEnvio=true;
				errorSistema=true;
				W83bClsTrazas.trazaError(null, "ERROR ENVIO CORRESPONDECIA AA66 "+e.getCause().getMessage()  ,e.getCause());
				break;
			}
		}
		
		//****************************************************************************************************
		//Comprobamos si ha habido error y regitramos el mensaje de vuelta al usuario
		//****************************************************************************************************
		
		
		StringBuffer mensajeError=new StringBuffer("");
		if(errorEnvio){
			if(!errorSistema && remesaOut.getErrores()!=null){
				if(hayEnvioCorrecto){
					mensajeError.append(Q70GestorMensajesi18n.getSingleton().getMessage("w83bcomun","comun.comunicaciones.enviocorrespondencianookParcial",idioma));
				}else{
					mensajeError.append(Q70GestorMensajesi18n.getSingleton().getMessage("w83bcomun","comun.comunicaciones.enviocorrespondencianook",idioma));
				}
					mensajeError.append(":<br>");
				
				//Recorremos los errores y añadimos una linea por error
				ErrorWs error;
				for (int i = 0; i < remesaOut.getErrores().length; i++) {
					error = (ErrorWs)remesaOut.getErrores()[i];
					
					//Comprobamos si lleva id para saber si es de un envío contreto o de toda la remesa o colección
					if(error.getIdErroneo()!=null){
						mensajeError.append(Q70GestorMensajesi18n.getSingleton().getMessage("w83bcomun","comun.comunicaciones.nActa",idioma));
						mensajeError.append(" ");
						mensajeError.append(error.getIdErroneo());
						mensajeError.append(": ");
					}
					
					if ("eu".equals(idioma)){
						mensajeError.append(error.getDescripcionEuskera());
						mensajeError.append("<br>");
					}else{
						mensajeError.append(error.getDescripcionCastellano());
						mensajeError.append("<br>");
					}
				
				}
			}else{
				
				if(hayEnvioCorrecto){
					mensajeError.append(Q70GestorMensajesi18n.getSingleton().getMessage("w83bcomun","comun.comunicaciones.enviocorrespondencianookSistemaParcial",idioma));
				}else{
					mensajeError.append(Q70GestorMensajesi18n.getSingleton().getMessage("w83bcomun","comun.comunicaciones.enviocorrespondencianookSistema",idioma));
				}
				
			}
		}
		
		//****************************************************************************************************
		//El envio ha sido parcial o totalmente correcto, regitramos datos envios remesa en las comunicaciones
		//****************************************************************************************************
		if(hayEnvioCorrecto){
			//Guardamos la lista de comunicaciones a actualizar en el contexto
			contexto.set("w83blistaComunicacionesAcuse",listaComunicacionesConAcuse);
			contexto.set("envioCorrespondenciaErrores",mensajeError.toString());
			//3.1.3 Retorno por "ok" para actualizar la comunicacion con los datos de la remesa de vuelta
			return mapping.findForward("ok");	
		}
		
		//*****************************************************
		//Ningún envío es correcto,sacamos errores por ventana
		//*****************************************************
		JSONObject raiz = new JSONObject();
		raiz.put("resultado",mensajeError.toString());
		response.setContentType("text/javascript;charset=iso-8859-1");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		response.setStatus(HttpServletResponse.SC_OK);
		PrintWriter out = response.getWriter();
		out.print(raiz.toString());
		out.flush();
		return null;
	}
	
	
	/**
	 * Divide en bloques de envios según el máximo de envíos permitido por AA66
	 * @param envios List
	 * @return List
	 * @throws Exception exception
	 */
	private List dividirBloques(List envios) throws Exception{
		List bloquesEnvio = new ArrayList();
		
		//Maximo y minimo de un bloque
		//Nota: aunque el minim sea solo para la remesa masiva en el caso de trocear lo vamos a tener en cuenta para los dos casos
		int maximoBloqueEnvio = Integer.valueOf(W83bProperties.getProperty("w83b","REMESA_MAXIMO")).intValue();
		int minimoBloqueEnvio = Integer.valueOf(W83bProperties.getProperty("w83b","REMESAMASIVA_MINIMO")).intValue();
		
		
		//Sumamos el minomo y el maximo para asegurarnos que no vamos a dejar un trozo del tamaño del minimo
		int minimoRecorrer=maximoBloqueEnvio+minimoBloqueEnvio;
		
		//Recorremos la lista de envios mientras sea menor que el minimoRecorrer
		int enviosSize = envios.size();
		int inicio = 0;
		int fin = 0;
		while(enviosSize>minimoRecorrer){
			fin = fin + maximoBloqueEnvio;
			bloquesEnvio.add(new ArrayList(envios.subList(inicio, fin)));
			inicio = inicio + maximoBloqueEnvio;
			enviosSize= enviosSize-maximoBloqueEnvio;
		}
		
		//Si es maayor de 180 pero menor que el limite recorrer dividimos por la mitad en dos bloques
		if(enviosSize>maximoBloqueEnvio){
			fin=fin+enviosSize/2;
			bloquesEnvio.add(new ArrayList(envios.subList(inicio, fin)));
			bloquesEnvio.add(new ArrayList(envios.subList(fin, envios.size())));
			
		}else{
			bloquesEnvio.add(new ArrayList(envios.subList(inicio, envios.size())));
		}
		
		
		
		return bloquesEnvio;
	}

}
